package ch.abcm.remsmobile.REMSMobile.utils;

import java.util.List;

import android.content.Context;
import android.util.Log;
import ch.abcm.remsmobile.REMSMobile.orm.DatabaseOpenHelper;
import ch.abcm.remsmobile.REMSMobile.orm.model.SystemState;
import ch.abcm.remsmobile.REMSMobile.orm.model.SystemState.State;
import ch.bfh.abcm.rems.gateway.GateWayMessageType;
import ch.bfh.abcm.rems.gateway.GatewayMessage;

import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.dao.RuntimeExceptionDao;

public class SystemStateController {

	private static final String TAG = "SystemStateController";
	private DatabaseOpenHelper databaseHelper;
	private RuntimeExceptionDao<SystemState, Integer> systemStateDao;

	public SystemStateController(Context context) {
		this.databaseHelper = OpenHelperManager.getHelper(context, DatabaseOpenHelper.class);
		this.systemStateDao = databaseHelper.getSystemStateRTEDao();
	}

	public boolean systemOKforEverySensorType() {
		boolean rv = true;
		List<SystemState> systemStates = systemStateDao.queryForAll();
		for (SystemState systemState : systemStates) {
			rv = rv && systemState.getSystemState().equals(State.SYSTEM_OK);
		}
		Log.d(TAG, "systemOKforEverySensorType: " + rv);
		return rv;
	}

	public void addSystemStateTypeIfNotExist(GatewayMessage gatewayMessage) {
		Log.d(TAG, "Search in DB for SystemState for Sensortype: " + gatewayMessage.getSensorType());
		if (gatewayMessage.getSensorType() != null) {

			List<SystemState> states = systemStateDao.queryForEq("sensorType", gatewayMessage.getSensorType());
			Log.d(TAG, "Found " + states.size() + " Entries");
			if (states.size() == 0) {
				Log.d(TAG, "This is a New Sensortype, creating new State in DB");
				SystemState systemState = createSystemState(gatewayMessage);
				systemStateDao.create(systemState);
				Log.d(TAG, "Creating new SystemState worked");
			} else {
				Log.d(TAG, "Systemstate already exist");
			}
		}
	}

	private State convertinSystemState(GateWayMessageType gateWayMessageType) {
		switch (gateWayMessageType) {
		case MEASUREMENT_DIVERGENCE:
			return State.MEASUREMENT_DIVERGENCE;
		case SYSTEM_ERROR:
			return State.SYSTEM_ERROR;
		case SYSTEM_OK:
			return State.SYSTEM_OK;
		case PERIODIC_NOTIFICATION:
			// Periodic notification is OK
			return State.SYSTEM_OK;
		default:
			Log.e(TAG, "Unexpected gateWayMessageType: " + gateWayMessageType);
			return State.SYSTEM_ERROR;
		}
	}

	private SystemState createSystemState(GatewayMessage gatewayMessage) {
		return new SystemState(convertinSystemState(gatewayMessage.getMessageType()), gatewayMessage.getSensorType());
	}

	public boolean systemStateIsNew(GatewayMessage gatewayMessage) {
		List<SystemState> systemStates = systemStateDao.queryForEq("sensorType", gatewayMessage.getSensorType());
		if (systemStates.size() == 1) {
			SystemState actualState = systemStates.get(0);
//			return actualState.equals(convertinSystemState(gatewayMessage.getMessageType()));
			boolean isnew = (actualState.getSystemState()+"").equals((gatewayMessage.getMessageType()+""));
			String one = actualState.getSystemState()+"";
			String two = gatewayMessage.getMessageType()+"";
			Log.d(TAG, "IsNew: "+isnew+" one: "+one +" two: "+two);
			return !isnew;
		} else {
			Log.e(TAG, "systemStateIsNew foud " + systemStates.size() + " States, expected was one...");
			return true;
		}
	}

	public void updateSystemState(GatewayMessage gatewayMessage) {
		Log.d(TAG, "updateSystemState...");
		SystemState systemState = findByGateWayMessage(gatewayMessage);
		State state = convertinSystemState(gatewayMessage.getMessageType());
		if (systemState != null) {
			systemState.setSystemState(state);
			systemStateDao.update(systemState);
			Log.i(TAG, "Update SystemState Successfull");
		} else {
			Log.e(TAG, "updateSystemState not possible, systemState in NULL");
		}

	}

	private SystemState findByGateWayMessage(GatewayMessage gatewayMessage) {
		List<SystemState> systemStates = systemStateDao.queryForEq("sensorType", gatewayMessage.getSensorType());
		switch (systemStates.size()) {
		case 0:
			Log.e(TAG, "findByGateWayMessage did not found a state...");
			return null;
		case 1:
			return systemStates.get(0);
		default:
			Log.e(TAG, "findByGateWayMessage found " + systemStates.size()
					+ " States expected was one, returning hte first");
			return systemStates.get(0);
		}
	}
}
